/*
轨迹处理类，使用方法
import mapTrickUtil from  'static/js/MapTrickUtil.js'

const Icon_Marker_Trick = makeIconTrick('/static/css/images/mapobj/marker-icon.png')

mapTrickUtil.showTrackInfo(mapobj,parentobj.tracklist,Icon_Marker_Trick);
mapTrickUtil.mapZoomEndMoveEndForTrick(mapobj);
mapTrickUtil.clearTrick(mapobj);
 */
class MapTrickUtil {

  constructor(){
    //this.属性=[]//初始化属性，这种公用属性是不需要单独声明的，直接用this.属性名 的方式赋值，但是需要初始化，如果想让属性被类的实例使用
    this.trackLineGroup = [];//单船轨迹线-显示在地图上对象
    this.trackArrowGroup = [];//单船轨迹线上的箭头-显示在地图上对象
    this.trackLatLngAry=[];//单船所有轨迹点-数据
    this.latlngs=[];//单船所有轨迹点，每个点的数据格式是[23.4,112.3]，数组数据格式[ [23.4,112.3],[23.4,112.3] ]
    this.gpsLabelAry=[];//单船轨迹线上的gps时间标签-显示在地图上对象
    this.gpsLabelLineAry=[];//单船轨迹线上的gps时间标签的连线-显示在地图上对象
    this.gpsLabelAryData=[];//单船轨迹线上的gps时间标签-显示在地图上对象-对应的轨迹数据
    this.trickLineColor="#6a3675";//轨迹线颜色
    this.trickLineWidth=2;//轨迹线宽度
    this.trickLabelLineColor="#6a3675";//gps时间标签连线颜色
    this.trickLabelLineWidth=1;//gps时间标签连线宽度
    this.trickArrowFillColor="#6a3675"; //轨迹线箭头填充颜色
    this.trickArrowFillOpacity=1;////轨迹线箭头填充透明度，1代表不透明
    this.trickArrowColor="#6a3675"; //轨迹线箭头边框颜色
    this.trickArrowWeight=1;//轨迹线箭头边框宽度
    this.trickArrowOpacity=1;//轨迹线箭头边框透明度，1代表不透明
    this.trickArrowAngle=20;//轨迹线监听角度（一半）
    this.trickArrowR=14;//轨迹线箭头两边长度
    this.trickArrowR1=8;//轨迹线箭头中间长度
    this.Ymax=1366;//像素Y的最大值
    this.gpsLabelWidth=105;//gps时间标签宽度
    this.gpsLabelHeight=20;//gps时间标签高度
    this.screenPointRoateAddValue=25;//获取gps时间标签连接线时进行旋转时增加的屏幕像素值
    this.showGpsLabel=true;
    this.convertGpsTimeLabel = this.convertGpsTimeLabel.bind(this); //保障convertGpsTimeLabel方法中的this是指向类的实例，如果不绑定，当方法提取出来单独使用，此方法中的this 会指向该方法运行时所在的环境，会造成此方法中通过this来调用的方法找不到
    this.getGpsLabelLine = this.getGpsLabelLine.bind(this);
    this.showGpsTimeLabel = this.showGpsTimeLabel.bind(this);
    this.showTrackInfo = this.showTrackInfo.bind(this);
    this.mapZoomEndMoveEndForTrick = this.mapZoomEndMoveEndForTrick.bind(this);
    this.convertGpsTimeLabelAndShow = this.convertGpsTimeLabelAndShow.bind(this);
    this.clearGpsLabelMapObj = this.clearGpsLabelMapObj.bind(this);
    this.clearTrick = this.clearTrick.bind(this);
    this.lnglatFilterByJiaoDu = this.lnglatFilterByJiaoDu.bind(this);
    this.lnglatFilterByJiaoDuForCount = this.lnglatFilterByJiaoDuForCount.bind(this);
    this.filterTrickPoint = this.filterTrickPoint.bind(this);
    this.RotatePointByRad = this.RotatePointByRad.bind(this);
    this.RotatePoint = this.RotatePoint.bind(this);
    this.getScreenPointFromOneMapPointLatLngAry = this.getScreenPointFromOneMapPointLatLngAry.bind(this);
    this.getOneMapPointLatLngAryFromScreenPoint = this.getOneMapPointLatLngAryFromScreenPoint.bind(this);
    this.getRectForRightTop = this.getRectForRightTop.bind(this);
    this.getRectForRightBottom = this.getRectForRightBottom.bind(this);
    this.getRectForLeftBottom = this.getRectForLeftBottom.bind(this);
    this.getRectForLeftTop = this.getRectForLeftTop.bind(this);
    this.getTrickArrowAndShow = this.getTrickArrowAndShow.bind(this);
  }

  //显示轨迹 lnglatList 的格式：
  //   // let onetrickconvert = {}
  //   //  onetrickconvert.lng = 119.766666;
  //   //  onetrickconvert.lat = 37.933333
  //   //  onetrickconvert.gpstime ='2019-08-01 10:13';
  //   // lnglatList.push(onetrickconvert);
  // 测试数据:
  /*
  lnglatList=[];
  let onetrickconvert = {gpstime:"2019-08-01 00:00",lat:38.19708,lng:119.8934};
  lnglatList.push(onetrickconvert);
  onetrickconvert = {gpstime:"2019-08-01 00:06",lat:38.21373,lng:119.881747};
  lnglatList.push(onetrickconvert);
  onetrickconvert = {gpstime:"2019-08-01 00:12",lat:38.22998,lng:119.869853};
  lnglatList.push(onetrickconvert);
  onetrickconvert = {gpstime:"2019-08-01 00:18",lat:38.2466,lng:119.857573};
  lnglatList.push(onetrickconvert);
  onetrickconvert = {gpstime:"2019-08-01 00:24",lat:38.263707,lng:119.847987};
  lnglatList.push(onetrickconvert);
  onetrickconvert = {gpstime:"2019-08-01 00:30",lat:38.28104,lng:119.83876};
  lnglatList.push(onetrickconvert);
  onetrickconvert = {gpstime:"2019-08-01 00:36",lat:38.298617,lng:119.82984};
  lnglatList.push(onetrickconvert);
  onetrickconvert = {gpstime:"2019-08-01 00:42",lat:38.314733,lng:119.816387};
  lnglatList.push(onetrickconvert);
  onetrickconvert = {gpstime:"2019-08-01 00:48",lat:38.327277,lng:119.798387};
  lnglatList.push(onetrickconvert);
  onetrickconvert = {gpstime:"2019-08-01 00:54",lat:38.338623,lng:119.779173};
  lnglatList.push(onetrickconvert);
  onetrickconvert = {gpstime:"2019-08-01 01:00",lat:38.349867,lng:119.7596};
  lnglatList.push(onetrickconvert);
  onetrickconvert = {gpstime:"2019-08-01 01:07",lat:38.361117,lng:119.740387};
  lnglatList.push(onetrickconvert);
  */
  showTrackInfo(mapobject,lnglatListAll){
    //let lnglatList=this.filterTrickPoint(lnglatListAll); //后台接口已经增加了过滤功能，所以前台不进行点的过滤
    let lnglatList=lnglatListAll;

    this.clearTrick(mapobject);

    let tricklineinfo=this.getTrickLineConvertInfo(lnglatList);
    this.trackLatLngAry=tricklineinfo.trackLatLngAry;
    this.latlngs=tricklineinfo.latlngs;
    this.trackLineGroup=this.getTrickLineMapObjGroup(mapobject);

    for (var i = 0; i < this.trackLineGroup.length; i++) {
      mapobject.addLayer(this.trackLineGroup[i]);
    }
    this.getTrickArrowAndShow(mapobject);

    this.convertGpsTimeLabelAndShow(mapobject);

    mapobject.fitBounds(tricklineinfo.bounds);
  }

  mapZoomEndMoveEndForTrick(mapobject){
    this.clearGpsLabelMapObj(mapobject);
    this.getTrickArrowAndShow(mapobject);
    this.convertGpsTimeLabelAndShow(mapobject);
  }
  setShowGpsLabel(isShow){
    this.showGpsLabel=isShow;
  }
  clearGpsLabelMapObj(mapobject){
    //清除轨迹线上的gps时间标签
    if (this.gpsLabelAry.length > 0) {
      for (var i = 0; i < this.gpsLabelAry.length; i++) {
        mapobject.removeLayer(this.gpsLabelAry[i]);
      }
    }
    if (this.gpsLabelLineAry.length > 0) {
      for (var i = 0; i < this.gpsLabelLineAry.length; i++) {
        mapobject.removeLayer(this.gpsLabelLineAry[i]);
      }
    }
    this.gpsLabelAry = [];
    this.gpsLabelLineAry = [];
    this.gpsLabelAryData=[];
  }
  convertGpsTimeLabelAndShow(mapobject){
    if (this.showGpsLabel){
      let retobj=this.convertGpsTimeLabel(mapobject,this.trackLatLngAry);
      this.gpsLabelAry=retobj.gpsLabelAry;
      this.gpsLabelLineAry=retobj.gpsLabelLineAry;
      this.gpsLabelAryData=retobj.gpsLabelAryData;
      this.showGpsTimeLabel(mapobject,this.gpsLabelAry,this.gpsLabelLineAry,this.gpsLabelAryData);
    }
  }
  clearTrick(mapobject){
    //清除轨迹线
    if (this.trackLineGroup.length > 0) {
      for (var i = 0; i < this.trackLineGroup.length; i++) {
        mapobject.removeLayer(this.trackLineGroup[i]);
      }
    }
    this.trackLineGroup = [];
    //清除轨迹线上的箭头
    if (this.trackArrowGroup.length > 0) {
      for (var i = 0; i < this.trackArrowGroup.length; i++) {
        mapobject.removeLayer(this.trackArrowGroup[i]);
      }
    }
    this.trackArrowGroup = [];

    //清楚gps标签相关地图对象
    this.clearGpsLabelMapObj(mapobject);

    this.latlngs=[];
    this.trackLatLngAry=[];
  }

  //过滤轨迹点，如果大于10个点，则只保留开始、结束、中间的9个点，共10段
  filterTrickPoint(lnglatListAll){
    if (lnglatListAll.length<=11){
      return lnglatListAll;
    }
    let retary= this.lnglatFilterByJiaoDuForCount(lnglatListAll,11);
    console.log(retary);
    return retary;
  }
  //根据经纬度计算角度
  GetJiaoDu(lat1, lng1, lat2, lng2){
    let x1 = lng1;
    let y1 = lat1;
    let x2 = lng2;
    let y2 = lat2;
    let pi = Math.PI;
    let w1 = y1 / 180 * pi;
    let j1 = x1 / 180 * pi;
    let w2 = y2 / 180 * pi;
    let j2 = x2 / 180 * pi;
    let ret;
    if (j1 == j2)
    {
      if (w1 > w2) return 270; //北半球的情况，南半球忽略
      else if (w1 < w2) return 90;
      else return -1;//位置完全相同
    }
    ret = 4 * Math.pow(Math.sin((w1 - w2) / 2), 2) - Math.pow(Math.sin((j1 - j2) / 2) * (Math.cos(w1) - Math.cos(w2)), 2);
    ret = Math.sqrt(ret);
    let temp = (Math.sin(Math.abs(j1 - j2) / 2) * (Math.cos(w1) + Math.cos(w2)));
    ret = ret / temp;
    ret = Math.atan(ret) / pi * 180;
    if (j1 > j2) // 1为参考点坐标
    {
      if (w1 > w2) ret += 180;
      else ret = 180 - ret;
    }
    else if (w1 > w2) ret = 360 - ret;
    return ret;
  }
  //将角度小于filterJiaoDu的点过滤掉，但是保留起点和终点
  lnglatFilterByJiaoDu(lnglatList,filterJiaoDu){
    if (lnglatList.length<=3){
      return lnglatList;
    }
    var retary=[];
    retary.push(lnglatList[0]);
    retary.push(lnglatList[1]);
    let prejiaodu=this.GetJiaoDu(lnglatList[0].lat,lnglatList[0].lng,lnglatList[1].lat,lnglatList[1].lng);
    for (let i=2;i<lnglatList.length-1;i++){
      let jaodu=this.GetJiaoDu(retary[retary.length-1].lat,retary[retary.length-1].lng,lnglatList[i].lat,lnglatList[i].lng);
      let cz=jaodu-prejiaodu;
      cz=Math.abs(cz);
      if (cz>=filterJiaoDu){
        retary.push(lnglatList[i]);
        prejiaodu=jaodu;
      }
    }
    retary.push(lnglatList[lnglatList.length-1]);
    return retary;
  }
  //保留起点和终点，要求只剩下一定个数的点
  lnglatFilterByJiaoDuForCount(lnglatList,pointcount){
    for(let i=1;i<90;i++){
      let retary=this.lnglatFilterByJiaoDu(lnglatList,i);
      if (retary.length<=pointcount){
        return retary;
      }
    }
    let retary=this.lnglatFilterByJiaoDu(lnglatList,90);
    return retary;
  }
  //获取轨迹线需要的转换信息,lnglatList 的格式：
  // let onetrickconvert = {}
  //  onetrickconvert.lng = 119.766666;
  //  onetrickconvert.lat = 37.933333
  //  onetrickconvert.gpstime ='2019-08-01 10:13';
  // lnglatList.push(onetrickconvert);
    getTrickLineConvertInfo(lnglatList){
      let latcenter=0;
      let latmax=0;
      let latmin=0;
      let lngcenter=0;
      let lngmax=0;
      let lngmin=0;

      let latlngs = [];
      let gpstimeary = [];
      let trackLatLngAry=[];

      for (let k = 0; k < lnglatList.length; k++) {
        let onelatlng = [lnglatList[k].lat, lnglatList[k].lng];
        latlngs.push(onelatlng);
        gpstimeary.push(lnglatList[k].gpstime);
        let oneTrickInfo={};
        oneTrickInfo.latlng=onelatlng;
        oneTrickInfo.gpstime=lnglatList[k].gpstime;
        trackLatLngAry.push(oneTrickInfo);
        if (latcenter==0){
          latmax=lnglatList[k].lat;
          latmin=lnglatList[k].lat;
          latcenter=lnglatList[k].lat;
        }else{
          if (lnglatList[k].lat>latmax){
            latmax=lnglatList[k].lat;
          }else if (lnglatList[k].lat<latmin){
            latmin=lnglatList[k].lat;
          }
        }
        if (lngcenter==0){
          lngmax=lnglatList[k].lng;
          lngmin=lnglatList[k].lng;
          lngcenter=lnglatList[k].lng;
        }else{
          if (lnglatList[k].lng>lngmax){
            lngmax=lnglatList[k].lng;
          }else if (lnglatList[k].lng<lngmin){
            lngmin=lnglatList[k].lng;
          }
        }
      }
      let corner1 = L.latLng(latmin, lngmin);
      let  corner2 = L.latLng(latmax, lngmax);
      let  bounds = L.latLngBounds(corner1, corner2);

      let retobj={};
      retobj.bounds=bounds;
      retobj.latlngs=latlngs;
      retobj.gpstimeary=gpstimeary;
      retobj.trackLatLngAry=trackLatLngAry;
      return retobj;
    }
  //对浮点数格式化，防止出现0.99999998的现象(f为浮点数，size中保留小数位数)
  formatfloat1(f,size){
    let tf=f*Math.pow(10,size);
    tf=Math.round(tf+0.000000001);
    tf=tf/Math.pow(10,size);
    return tf;
  }
  //获取两个点连成的线段中间点
  getMidPoint(A,B){
  let xmin=0;
  let xmax=0;
  let ymin=0;
  let ymax=0;
  if (A.x>B.x){
    xmax=A.x;
    xmin=B.x;
  }else{
    xmax=B.x;
    xmin=A.x;
  }
  if (A.y>B.y){
    ymax=A.y;
    ymin=B.y;
  }else{
    ymax=B.y;
    ymin=A.y;
  }
  let ret={};
  ret.x=xmin+(xmax-xmin)/2;
  ret.y=ymin+(ymax-ymin)/2;
  return ret;
  }
  //以A为原点(0,0)，计算B点与X轴（A点向右延伸为X轴正）正方向的夹角(夹角弧度)，相当于正东为0，逆时针旋转增大
  getJd(A,B){
  let newp=[];
  newp.x=B.x-A.x;
  newp.y=A.y-B.y;
  let hd=this.radPOX(newp.x,newp.y);
  let uninconvert=180/Math.PI;
  let jd=hd*uninconvert;
  return jd;
  }
  //根据圆心、半径、角度，获取圆上的点，X轴正方向为0，即正东为0，顺时针旋转角度增大
  getCirclePoint(A,r,jd){
  let hudu = (2*Math.PI / 360) * jd;  //弧度的计算公式为： 2*PI/360*角度；
  let x=A.x + Math.cos(hudu) * r;
  let y=A.y + Math.sin(hudu) * r;
  let ret={};
  ret.x=this.formatfloat1(x,6);
  ret.y=this.formatfloat1(y,6);
  return ret;
  }
  //获取A到B的线段的中间点的箭头,A起点，B终点，r箭头两边的长度，r1箭头中间的长度,arrorjd箭头两边的角度的一半
  getArrowPointAry(A,B,r,r1,arrorjd){
  let midPoint=this.getMidPoint(A,B);
  let jd=this.getJd(midPoint,A); //角度是逆时针增大
  jd=360-jd; //转成顺时针增大，因为获取圆上的点是顺时针增大
  let arrorhend1jd=jd+arrorjd;
  if (arrorhend1jd>=360){
    arrorhend1jd=arrorhend1jd-360;
  }
  let arrorhend2jd=jd-arrorjd;
  if (arrorhend2jd<0){
    arrorhend2jd=360+arrorhend2jd;
  }
  let arrorhead1P=this.getCirclePoint(midPoint,r,arrorhend1jd);
  let arrorhead2P=this.getCirclePoint(midPoint,r,arrorhend2jd);
  let arrormid1=null;
  if (r1>0){
    arrormid1=this.getCirclePoint(midPoint,r1,jd);
  }
  let ret=[];
  ret.push(arrorhead1P);
  ret.push(midPoint);
  ret.push(arrorhead2P);
  if (r1>0){
    ret.push(arrormid1);
  }
  return ret;
  }
  //获取地图轨迹线、起点、终点对象的数组
    getTrickLineMapObjGroup(mapobject){
      let latlngs=this.latlngs;
      let trackLineGroup=[];
      let latlng;
      let i=0;
      for (i = 0; i < latlngs.length; i++) {
        if (i == 0) {
          latlng = latlngs[i];
        } else {
          let arrow = L.polyline([latlng, latlngs[i]], {color: this.trickLineColor, weight: this.trickLineWidth});
          trackLineGroup.push(arrow);
          //线上的箭头，后面单独处理了，为了和传讯网一致
/*
          let arrowHead = L.polylineDecorator(arrow, {
            patterns: [
              {
                offset: '50%',
                repeat: 0,
                symbol: L.Symbol.arrowHead({pixelSize: 10, polygon: false, pathOptions: {stroke: true, color: this.trickLineColor}})
              }
            ]
          });
          trackLineGroup.push(arrowHead);
*/
          latlng = latlngs[i];
        }
      }

      //绘制起点 终点 小圆点
      for (i = 0; i < latlngs.length; i++) {
        //小圆点外层
        let circleMarkerW = L.circleMarker([latlngs[i][0], latlngs[i][1]], {color:this.trickLineColor, radius: 3});
        trackLineGroup.push(circleMarkerW);
        //小圆点里层
        let circleMarkerN = L.circleMarker([latlngs[i][0], latlngs[i][1]], {color:"#ffffff", radius: 1});
        trackLineGroup.push(circleMarkerN);
        if (i == 0) {//起点
          let circleMarker1 = L.circleMarker([latlngs[i][0], latlngs[i][1]], {color:this.trickLineColor, radius: 8});
          trackLineGroup.push(circleMarker1);
          let circleMarker2 = L.circleMarker([latlngs[i][0], latlngs[i][1]], {color:"#ffffff", radius: 6});
          trackLineGroup.push(circleMarker2);
          let circleMarker3 = L.circleMarker([latlngs[i][0], latlngs[i][1]], {color:"#3E9F73", radius: 3});
          trackLineGroup.push(circleMarker3);
          circleMarker3 = L.circleMarker([latlngs[i][0], latlngs[i][1]], {color:"#3E9F73", radius: 2});
          trackLineGroup.push(circleMarker3);
          circleMarker3 = L.circleMarker([latlngs[i][0], latlngs[i][1]], {color:"#3E9F73", radius: 1});
          trackLineGroup.push(circleMarker3);
          /*
          let offetpoint = L.point(0, -20);
          var markerStart = L.marker([latlngs[i][0], latlngs[i][1]], {opacity: 0.8,icon:Icon_Marker_Trick_Start}).bindTooltip("起点", {
            opacity: 1,
            permanent: true,
            direction: top,
            className: 'my-div-icon2',
            offset:offetpoint
          });
          trackLineGroup.push(markerStart);
          */
        }
        if (i == latlngs.length - 1) { //终点
          let circleMarker1 = L.circleMarker([latlngs[i][0], latlngs[i][1]], {color:this.trickLineColor, radius: 8});
          trackLineGroup.push(circleMarker1);
          let circleMarker2 = L.circleMarker([latlngs[i][0], latlngs[i][1]], {color:"#ffffff", radius: 6});
          trackLineGroup.push(circleMarker2);
          let circleMarker3 = L.circleMarker([latlngs[i][0], latlngs[i][1]], {color:"#ff0000", radius: 3});
          trackLineGroup.push(circleMarker3);
          circleMarker3 = L.circleMarker([latlngs[i][0], latlngs[i][1]], {color:"#ff0000", radius: 2});
          trackLineGroup.push(circleMarker3);
          circleMarker3 = L.circleMarker([latlngs[i][0], latlngs[i][1]], {color:"#ff0000", radius: 1});
          trackLineGroup.push(circleMarker3);
          /*
          let offetpoint = L.point(0, 20);
          var markerEnd = L.marker([latlngs[i][0], latlngs[i][1]], {opacity: 0.8,icon:Icon_Marker_Trick_End}).bindTooltip("终点", {
            opacity: 1,
            permanent: true,
            direction: top,
            className: 'my-div-icon3',
            offset:offetpoint
          });
          trackLineGroup.push(markerEnd);
          */
        }
      }
      return trackLineGroup;
    }
    //获取并显示轨迹线上的箭头
    getTrickArrowAndShow(mapobject){
      //清除轨迹线上的箭头
      if (this.trackArrowGroup.length > 0) {
        for (let m = 0; m < this.trackArrowGroup.length; m++) {
          mapobject.removeLayer(this.trackArrowGroup[m]);
        }
      }
      this.trackArrowGroup=[];

      let latlngs=this.latlngs;
      let latlng;
      let i=0;
      for (i = 0; i < latlngs.length; i++) {
        if (i == 0) {
          latlng = latlngs[i];
        } else {
          let startpoint=mapobject.project(latlng);
          let endpoint=mapobject.project(latlngs[i]);
          let arrorPointAry = this.getArrowPointAry(startpoint,endpoint,this.trickArrowR,this.trickArrowR1,this.trickArrowAngle);
          let arrorMapPointAry=[];
          for (let n=0;n<arrorPointAry.length;n++){
            let mapPoint=mapobject.unproject(arrorPointAry[n]);
            arrorMapPointAry.push(mapPoint);
          }
          let arrowHead = L.polygon(arrorMapPointAry, {fillColor:this.trickArrowFillColor,fillOpacity:this.trickArrowFillOpacity, color: this.trickArrowColor,weight: this.trickArrowWeight,opacity:this.trickArrowOpacity});
          this.trackArrowGroup.push(arrowHead);
          /*
          let arrow = L.polyline([latlng, latlngs[i]], {color: this.trickLineColor, weight: this.trickLineWidth});
                    let arrowHead = L.polylineDecorator(arrow, {
                      patterns: [
                        {
                          offset: '50%',
                          repeat: 0,
                          symbol: L.Symbol.arrowHead({pixelSize: 10, polygon: false, pathOptions: {stroke: true, color: this.trickLineColor}})
                        }
                      ]
                    });
                    this.trackArrowGroup.push(arrowHead);
          */
          latlng = latlngs[i];
        }
      }
      for (i = 0; i < this.trackArrowGroup.length; i++) {
        mapobject.addLayer(this.trackArrowGroup[i]);
      }
    }
    //根据当前地图范围进行gps标签的过滤
    //trackLatLngAry ： getTrickLineConvertInfo函数返回对象的trackLatLngAry属性
    convertGpsTimeLabel(mapobject,trackLatLngAry){
      let gpsLabelAry=[];
      let gpsLabelLineAry=[];
      let gpsLabelAryData=[];

      let mapBoundsLngMin = mapobject.getBounds().getSouthWest().lng;
      let mapBoundsLngMax = mapobject.getBounds().getNorthEast().lng;
      let mapBoundsLatMin=mapobject.getBounds().getSouthWest().lat;
      let mapBoundsLatMax = mapobject.getBounds().getNorthEast().lat;
      let yxdata=[];
      let endpointisYx=false;
      if (trackLatLngAry.length>1){
        let oneTrickInfoend = trackLatLngAry[trackLatLngAry.length-1];
        let latlngsend = oneTrickInfoend.latlng;
        if ( latlngsend[0]>=mapBoundsLatMin && latlngsend[0]<=mapBoundsLatMax
          && latlngsend[1]>=mapBoundsLngMin && latlngsend[1]<=mapBoundsLngMax ){
          endpointisYx=true;
        }
      }
      for (let i=0;i<trackLatLngAry.length;i++) {
        var oneTrickInfo = trackLatLngAry[i];
        let latlngone = oneTrickInfo.latlng;
        if ( latlngone[0]>=mapBoundsLatMin && latlngone[0]<=mapBoundsLatMax
          && latlngone[1]>=mapBoundsLngMin && latlngone[1]<=mapBoundsLngMax ){
          if (i==0){
            oneTrickInfo.bz="start";
            let A=this.getScreenPointFromOneMapPointLatLngAry(mapobject,oneTrickInfo.latlng);
            let rect=this.getRectForRightTop(A,this.gpsLabelWidth,this.gpsLabelHeight,this.screenPointRoateAddValue);
            oneTrickInfo.rect=rect;
            yxdata.push(oneTrickInfo);
          }else if (i==trackLatLngAry.length-1){
            oneTrickInfo.bz="end";
            let A=this.getScreenPointFromOneMapPointLatLngAry(mapobject,oneTrickInfo.latlng);
            let rect=this.getRectForRightTop(A,this.gpsLabelWidth,this.gpsLabelHeight,this.screenPointRoateAddValue);
            oneTrickInfo.rect=rect;
            yxdata.push(oneTrickInfo);
          }else{
            oneTrickInfo.bz="mid";
              let oneTrickInfoend = trackLatLngAry[trackLatLngAry.length-1];
              let checkresult=this.gpsLabelIsShow(mapobject,yxdata,latlngone,endpointisYx,oneTrickInfoend,this.gpsLabelWidth,this.gpsLabelHeight);
              if (checkresult.result){
                oneTrickInfo.rect=checkresult.rect;
                yxdata.push(oneTrickInfo);
              }
          }
        }
      }
      if (yxdata.length>10){ //只留10个，第一个和最后一个必须保留
        let newary=[];
        newary.push(yxdata[0]);
        let jg=yxdata.length/10;
        for (let i=1;i<=8;i++){
          let newindex=i*jg;
          newindex=Math.round(newindex);
          if (newindex<yxdata.length-1){
            newary.push(yxdata[newindex]);
          }
        }
        newary.push(yxdata[yxdata.length-1]);
        yxdata=[];
        for(let k=0;k<newary.length;k++){
          yxdata.push(newary[k]);
        }
        console.log(yxdata);
      }
      if (yxdata.length>0){
        for (let i=0;i<yxdata.length;i++){
          var oneTrickInfo=yxdata[i];
          var tooltip =this.getGpsLabel(oneTrickInfo);
          gpsLabelAry.push(tooltip);

          let labelLine =this.getGpsLabelLine(mapobject,oneTrickInfo);
          gpsLabelLineAry.push(labelLine);

          gpsLabelAryData.push(oneTrickInfo);
        }
      }
      let retobj={};
      retobj.gpsLabelAry=gpsLabelAry;
      retobj.gpsLabelLineAry=gpsLabelLineAry;
      retobj.gpsLabelAryData=gpsLabelAryData;
      return retobj;
    }
    getGpsLabel(oneTrickInfo){
      let latlngone=oneTrickInfo.latlng;
      let gpstime=oneTrickInfo.gpstime;
      let gpslabelOffsetX;
      let gpslabelOffsetY;
      gpslabelOffsetX=oneTrickInfo.rect.labelOffSetX;
      gpslabelOffsetY=oneTrickInfo.rect.labelOffSetY;
      var tooltip = L.tooltip({
        opacity: 1,
        direction:'right',
        permanent: true,
        interactive: true,
        className: 'my-div-icon',
        offset:[gpslabelOffsetX,gpslabelOffsetY]
      }).setLatLng([latlngone[0], latlngone[1]]).setContent(gpstime);
      return tooltip;
    }
    getGpsLabelLine(mapobject,oneTrickInfo){
      let latlngone=oneTrickInfo.latlng;
      let latlngtwo1=this.getOneMapPointLatLngAryFromScreenPoint(mapobject,oneTrickInfo.rect.linkPoint);
      let linedata=[];
      linedata.push(latlngone);
      linedata.push(latlngtwo1);
      let labelLine = L.polyline(linedata, {color: this.trickLabelLineColor, weight: this.trickLabelLineWidth});
      return labelLine;
    }
    //从latlng数组转成屏幕坐标
    getScreenPointFromOneMapPointLatLngAry(mapobject,latlngone){
      let latlngtemp = L.latLng(latlngone[0],latlngone[1]);
      let screenPointA=mapobject.latLngToContainerPoint(latlngtemp);
      let A={};
      A.x=screenPointA.x;
      A.y=this.Ymax-screenPointA.y;
      return A;
    }
  //从屏幕坐标转成latlng数组
    getOneMapPointLatLngAryFromScreenPoint(mapobject,screenPoint){
      let layerP=L.point(Math.ceil(screenPoint.x),Math.ceil(this.Ymax-screenPoint.y));
      let latlngtwo=mapobject.containerPointToLatLng(layerP);
      let latlngtwo1=[latlngtwo.lat,latlngtwo.lng];
      return latlngtwo1;
    }
  //gpstime标签是否显示
  gpsLabelIsShow(mapobject,yxdata,latlngone,endpointisYx,oneTrickInfoend,labelwidth,labelheight){
    var isShow=true;
    let A=this.getScreenPointFromOneMapPointLatLngAry(mapobject,latlngone);
    let rect=this.getRectForRightTop(A,this.gpsLabelWidth,this.gpsLabelHeight,this.screenPointRoateAddValue);
    for (let k=0;k<yxdata.length;k++){
      if (this.rectIsCross(yxdata[k].rect,rect)){
        isShow=false;
      }
    }
    if (!isShow){
      isShow=true;
      rect=this.getRectForRightBottom(A,this.gpsLabelWidth,this.gpsLabelHeight,this.screenPointRoateAddValue);
      for (let k=0;k<yxdata.length;k++){
        if (this.rectIsCross(yxdata[k].rect,rect)){
          isShow=false;
        }
      }
    }
    if (!isShow){
      isShow=true;
      rect=this.getRectForLeftBottom(A,this.gpsLabelWidth,this.gpsLabelHeight,this.screenPointRoateAddValue);
      for (let k=0;k<yxdata.length;k++){
        if (this.rectIsCross(yxdata[k].rect,rect)){
          isShow=false;
        }
      }
    }
    if (!isShow){
      isShow=true;
      rect=this.getRectForLeftTop(A,this.gpsLabelWidth,this.gpsLabelHeight,this.screenPointRoateAddValue);
      for (let k=0;k<yxdata.length;k++){
        if (this.rectIsCross(yxdata[k].rect,rect)){
          isShow=false;
        }
      }
    }
    if (!isShow){
      let resultobj={};
      resultobj.result=false;
      return resultobj;
    }
    if (endpointisYx){
      let A=this.getScreenPointFromOneMapPointLatLngAry(mapobject,oneTrickInfoend.latlng);
      let rectend=this.getRectForRightTop(A,this.gpsLabelWidth,this.gpsLabelHeight,this.screenPointRoateAddValue);
      if (this.rectIsCross(rectend,rect)){
        let resultobj={};
        resultobj.result=false;
        return resultobj;
      }else{
        let resultobj={};
        resultobj.result=true;
        resultobj.rect=rect;
        return resultobj;
      }
    }else{
      let resultobj={};
      resultobj.result=true;
      resultobj.rect=rect;
      return resultobj;
    }
  }

  isInteger(obj) {
    return obj%1 === 0
  }

  //两个矩形是否相交，以左下角为0 0 坐标,x向右为正，越来越大，Y向上为正，越来越大
  rectIsCross(rect1,rect2){
    let jladd=5;//间隔距离
    if ( (rect1.x+rect1.w+jladd)<rect2.x ){
      return false;
    }
    if ( (rect1.y+rect1.h+jladd)<rect2.y ){
      return false;
    }
    if ( (rect2.x+rect2.w+jladd)<rect1.x ){
      return false;
    }
    if  ( (rect2.y+rect2.h+jladd)<rect1.y ){
      return false;
    }
    return true;
  }
  //获取右上角的矩形,A,中心点，addScreenValue 扩展的像素值，以左下角为0 0 坐标,x向右为正，越来越大，Y向上为正，越来越大
  getRectForRightTop(A,w,h,addScreenValue){
    var P={};
    P.x=A.x;
    P.y=A.y+addScreenValue;
    var rotate=this.RotatePoint(P,A,55,true);
    var ret={};
    ret.left=rotate.x;
    ret.right=rotate.x+w;
    ret.top=rotate.y+h;
    ret.bottom=rotate.y;
    ret.x=ret.left;
    ret.y=ret.top;
    ret.w=w;
    ret.h=h;
    ret.linkPoint={};
    ret.linkPoint.x=rotate.x;
    ret.linkPoint.y=rotate.y;
    ret.labelOffSetX=rotate.x-A.x-5;
    ret.labelOffSetY=0-((rotate.y-A.y)+10);
    ret.wz="righttop";
    return ret;
  }
  //获取右下角的矩形,A,中心点，addScreenValue 扩展的像素值，以左下角为0 0 坐标,x向右为正，越来越大，Y向上为正，越来越大
  getRectForRightBottom(A,w,h,addScreenValue){
    var P={};
    P.x=A.x;
    P.y=A.y+addScreenValue;
    var rotate=this.RotatePoint(P,A,125,true);
    var ret={};
    ret.left=rotate.x;
    ret.right=rotate.x+w;
    ret.top=rotate.y;
    ret.bottom=rotate.y-h;
    ret.x=ret.left;
    ret.y=ret.top;
    ret.w=w;
    ret.h=h;
    ret.linkPoint={};
    ret.linkPoint.x=rotate.x;
    ret.linkPoint.y=rotate.y;
    ret.labelOffSetX=rotate.x-A.x+1-5;
    ret.labelOffSetY=A.y-rotate.y+10;
    ret.wz="rightbottom";
    return ret;
  }
  //获取左下角的矩形,A,中心点，addScreenValue 扩展的像素值，以左下角为0 0 坐标,x向右为正，越来越大，Y向上为正，越来越大
  getRectForLeftBottom(A,w,h,addScreenValue){
    var P={};
    P.x=A.x;
    P.y=A.y+addScreenValue;
    var rotate=this.RotatePoint(P,A,125,false);
    var ret={};
    ret.left=rotate.x-w;
    ret.right=rotate.x;
    ret.top=rotate.y;
    ret.bottom=rotate.y-h;
    ret.x=ret.left;
    ret.y=ret.top;
    ret.w=w;
    ret.h=h;
    ret.linkPoint={};
    ret.linkPoint.x=rotate.x;
    ret.linkPoint.y=rotate.y;
    ret.labelOffSetX=0-((A.x-rotate.x)+w+4);
    ret.labelOffSetY=A.y-rotate.y+10;
    ret.wz="leftbottom";
    return ret;
  }
  //获取左上角的矩形,A,中心点，addScreenValue 扩展的像素值，以左下角为0 0 坐标,x向右为正，越来越大，Y向上为正，越来越大
  getRectForLeftTop(A,w,h,addScreenValue){
    var P={};
    P.x=A.x;
    P.y=A.y+addScreenValue;
    var rotate=this.RotatePoint(P,A,55,false);
    var ret={};
    ret.left=rotate.x-w;
    ret.right=rotate.x;
    ret.top=rotate.y+h;
    ret.bottom=rotate.y;
    ret.x=ret.left;
    ret.y=ret.top;
    ret.w=w;
    ret.h=h;
    ret.linkPoint={};
    ret.linkPoint.x=rotate.x;
    ret.linkPoint.y=rotate.y;
    ret.labelOffSetX=0-((A.x-rotate.x)+w+4);
    ret.labelOffSetY=0-((rotate.y-A.y)+10);
    ret.wz="lefttop";
    return ret;
  }

  //两个屏幕点之间距离
  PointDistance(P,A)
  {
    return Math.sqrt((P.x-A.x)*(P.x-A.x)+(P.y-A.y)*(P.y-A.y));
  }
  // 计算点(x,y)与X轴正方向的夹角(夹角弧度)
  //x:横坐标  y:纵坐标
  radPOX(x,y)
  {
    //P在(0,0)的情况
    if (x == 0 && y == 0) return 0;
    //P在四个坐标轴上的情况：x正、x负、y正、y负
    if (y == 0 && x > 0) return 0;
    if (y == 0 && x < 0) return Math.PI;
    if (x == 0 && y > 0) return Math.PI / 2;
    if (x == 0 && y < 0) return Math.PI / 2 * 3;
    //点在第一、二、三、四象限时的情况
    if (x > 0 && y > 0) return Math.atan(y / x);
    if (x < 0 && y > 0) return Math.PI - Math.atan(y / -x);
    if (x < 0 && y < 0) return Math.PI + Math.atan(-y / -x);
    if (x > 0 && y < 0) return Math.PI * 2 - Math.atan(-y / x);
    return 0;
  }
  // 返回点P围绕点A旋转弧度rad后的坐标
  // <param name="P">待旋转点坐标</param>
  // <param name="A">旋转中心坐标</param>
  // <param name="rad">旋转弧度，和我们理解的一周360度不是一个单位，半径长的圆弧所对的圆心角叫做1弧度的角</param>
  // <param name="isClockwise">true:顺时针/false:逆时针</param>
  // <returns>旋转后坐标</returns>
  RotatePointByRad(P,A,rad,isClockwise)
  {
    let Temp1={}; //点Temp1
    Temp1.x=P.x - A.x;
    Temp1.y=P.y - A.y;

    let P0={};
    P0.x=0;
    P0.y=0;
    //点Temp1到原点(0,0)的长度
    let lenO2Temp1 = this.PointDistance(P0,Temp1);
    //∠T1OX弧度
    let angT1OX = this.radPOX(Temp1.x, Temp1.y);
    //∠T2OX弧度（T2为T1以O为圆心旋转弧度rad）
    let angT2OX;
    if (isClockwise){
      angT2OX = angT1OX - rad;
    }else{
      angT2OX = angT1OX + rad;
    }
    //点Temp2
    let Temp2x=lenO2Temp1 * Math.cos(angT2OX);
    let Temp2y=lenO2Temp1 * Math.sin(angT2OX);

    let retx=Temp2x+A.x;
    let rety=Temp2y+A.y;

    let ret={x:retx,y:rety};

    return ret;
  }
  //返回点P围绕点A旋转角度a后的坐标
  RotatePoint(P,A,a,isClockwise){
    let convertunit=Math.PI/180;  //角度与弧度的转换单位
    let rad=convertunit*a;
    return this.RotatePointByRad(P,A,rad,isClockwise);
  }

    //显示gpstime标签
    showGpsTimeLabel(mapobject,gpsLabelAry,gpsLabelLineAry,gpsLabelAryData){
      if (gpsLabelAry.length==1){
        mapobject.addLayer(gpsLabelAry[0]);
        mapobject.addLayer(gpsLabelLineAry[0]);
      }else if (gpsLabelAry.length==2){
        if (gpsLabelAryData[0].bz=="start"){
          mapobject.addLayer(gpsLabelAry[1]);
          mapobject.addLayer(gpsLabelAry[0]);
          mapobject.addLayer(gpsLabelLineAry[1]);
          mapobject.addLayer(gpsLabelLineAry[0]);
        }else if (gpsLabelAryData[1].bz=="end"){
          mapobject.addLayer(gpsLabelAry[0]);
          mapobject.addLayer(gpsLabelAry[1]);
          mapobject.addLayer(gpsLabelLineAry[0]);
          mapobject.addLayer(gpsLabelLineAry[1]);
        }else {
          mapobject.addLayer(gpsLabelAry[0]);
          mapobject.addLayer(gpsLabelAry[1]);
          mapobject.addLayer(gpsLabelLineAry[0]);
          mapobject.addLayer(gpsLabelLineAry[1]);
        }
      }else if (gpsLabelAry.length==3){
        mapobject.addLayer(gpsLabelAry[1]);
        mapobject.addLayer(gpsLabelAry[0]);
        mapobject.addLayer(gpsLabelAry[2]);
        mapobject.addLayer(gpsLabelLineAry[1]);
        mapobject.addLayer(gpsLabelLineAry[0]);
        mapobject.addLayer(gpsLabelLineAry[2]);
      }else if (gpsLabelAry.length>3){
        let startindex=gpsLabelAry.length/2;
        if (!this.isInteger(startindex)){
          startindex=Math.ceil(startindex);
        }
        for (var k=startindex+1;k<gpsLabelAry.length;k++){
          mapobject.addLayer(gpsLabelAry[k]);
          mapobject.addLayer(gpsLabelLineAry[k]);
        }
        for (var m=startindex;m>=0;m--){
          mapobject.addLayer(gpsLabelAry[m]);
          mapobject.addLayer(gpsLabelLineAry[m]);
        }
      }
    }

}
export default new MapTrickUtil()
